package karma.pool.util.clock;

import java.util.concurrent.TimeUnit;

import static java.util.concurrent.TimeUnit.*;

/**
 * A resolution-independent provider of current time-stamps and elapsed time
 * calculations.
 */
public interface Clock {
   TimeUnit[] TIMEUNITS_DESCENDING = {DAYS, HOURS, MINUTES, SECONDS, MILLISECONDS, MICROSECONDS, NANOSECONDS};
   String[] TIMEUNIT_DISPLAY_VALUES = {"ns", "µs", "ms", "s", "m", "h", "d"};


   long currentTime();

   long toMillis(long time);

   long toNanos(long time);

   long elapsedMillis(long startTime);

   long elapsedMillis(long startTime, long endTime);

   long elapsedNanos(long startTime);

   long elapsedNanos(long startTime, long endTime);

   long plusMillis(long time, long millis);


   default String elapsedDisplayString0(long startTime, long endTime) {
      long elapsedNanos = elapsedNanos(startTime, endTime);

      StringBuilder sb = new StringBuilder(elapsedNanos < 0 ? "-" : "");
      elapsedNanos = Math.abs(elapsedNanos);

      for (TimeUnit unit : TIMEUNITS_DESCENDING) {
         long converted = unit.convert(elapsedNanos, NANOSECONDS);
         if (converted > 0) {
            sb.append(converted).append(TIMEUNIT_DISPLAY_VALUES[unit.ordinal()]);
            elapsedNanos -= NANOSECONDS.convert(converted, unit);
         }
      }

      return sb.toString();
   }

}
